Browse Source

Add HandlerProvider interface

HandlerProvider is now an interface that can be used to plug in
WebSocket handlers with per-connection scope semantics. There are two
implementations, of the interface, one simple and a second that creates
handler instances through AutowireCapableBeanFactory.

HandlerProvider also provides a destroy method that is used to
apply a destroy callback whenever a client connection closes.
pull/292/head
Rossen Stoyanchev 13 years ago
parent
commit
84089bf396
  1. 21
      spring-websocket/src/main/java/org/springframework/sockjs/AbstractSockJsSession.java
  2. 3
      spring-websocket/src/main/java/org/springframework/sockjs/SockJsSessionFactory.java
  3. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractServerSockJsSession.java
  4. 11
      spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractSockJsService.java
  5. 3
      spring-websocket/src/main/java/org/springframework/sockjs/server/SockJsService.java
  6. 3
      spring-websocket/src/main/java/org/springframework/sockjs/server/TransportHandler.java
  7. 18
      spring-websocket/src/main/java/org/springframework/sockjs/server/support/DefaultSockJsService.java
  8. 26
      spring-websocket/src/main/java/org/springframework/sockjs/server/support/SockJsHttpRequestHandler.java
  9. 3
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpReceivingTransportHandler.java
  10. 3
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpSendingTransportHandler.java
  11. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpServerSockJsSession.java
  12. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractStreamingTransportHandler.java
  13. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/JsonpPollingTransportHandler.java
  14. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/PollingServerSockJsSession.java
  15. 40
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/SockJsWebSocketHandler.java
  16. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/StreamingServerSockJsSession.java
  17. 19
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/WebSocketTransportHandler.java
  18. 5
      spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrPollingTransportHandler.java
  19. 94
      spring-websocket/src/main/java/org/springframework/websocket/HandlerProvider.java
  20. 10
      spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketClient.java
  21. 16
      spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketConnectionManager.java
  22. 19
      spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/AnnotatedEndpointConnectionManager.java
  23. 14
      spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManager.java
  24. 15
      spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/StandardWebSocketClient.java
  25. 69
      spring-websocket/src/main/java/org/springframework/websocket/endpoint/WebSocketHandlerEndpoint.java
  26. 7
      spring-websocket/src/main/java/org/springframework/websocket/server/DefaultHandshakeHandler.java
  27. 15
      spring-websocket/src/main/java/org/springframework/websocket/server/HandshakeHandler.java
  28. 5
      spring-websocket/src/main/java/org/springframework/websocket/server/RequestUpgradeStrategy.java
  29. 21
      spring-websocket/src/main/java/org/springframework/websocket/server/endpoint/EndpointRegistration.java
  30. 88
      spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointContainerFactoryBean.java
  31. 7
      spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointUpgradeStrategy.java
  32. 22
      spring-websocket/src/main/java/org/springframework/websocket/server/support/WebSocketHttpRequestHandler.java
  33. 94
      spring-websocket/src/main/java/org/springframework/websocket/support/BeanCreatingHandlerProvider.java
  34. 61
      spring-websocket/src/main/java/org/springframework/websocket/support/SimpleHandlerProvider.java

21
spring-websocket/src/main/java/org/springframework/sockjs/AbstractSockJsSession.java

@ -22,6 +22,7 @@ import org.apache.commons.logging.Log; @@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.TextMessageHandler;
import org.springframework.websocket.WebSocketHandler;
@ -40,6 +41,8 @@ public abstract class AbstractSockJsSession implements WebSocketSession { @@ -40,6 +41,8 @@ public abstract class AbstractSockJsSession implements WebSocketSession {
private final String sessionId;
private final HandlerProvider<WebSocketHandler> handlerProvider;
private final TextMessageHandler handler;
private State state = State.NEW;
@ -52,14 +55,17 @@ public abstract class AbstractSockJsSession implements WebSocketSession { @@ -52,14 +55,17 @@ public abstract class AbstractSockJsSession implements WebSocketSession {
/**
*
* @param sessionId
* @param handler the recipient of SockJS messages
* @param handlerProvider the recipient of SockJS messages
*/
public AbstractSockJsSession(String sessionId, WebSocketHandler webSocketHandler) {
public AbstractSockJsSession(String sessionId, HandlerProvider<WebSocketHandler> handlerProvider) {
Assert.notNull(sessionId, "sessionId is required");
Assert.notNull(webSocketHandler, "webSocketHandler is required");
Assert.isInstanceOf(TextMessageHandler.class, webSocketHandler, "Expected a TextMessageHandler");
Assert.notNull(handlerProvider, "handlerProvider is required");
this.sessionId = sessionId;
WebSocketHandler webSocketHandler = handlerProvider.getHandler();
Assert.isInstanceOf(TextMessageHandler.class, webSocketHandler, "Expected a TextMessageHandler");
this.handler = (TextMessageHandler) webSocketHandler;
this.handlerProvider = handlerProvider;
}
public String getId() {
@ -180,7 +186,12 @@ public abstract class AbstractSockJsSession implements WebSocketSession { @@ -180,7 +186,12 @@ public abstract class AbstractSockJsSession implements WebSocketSession {
}
finally {
this.state = State.CLOSED;
this.handler.afterConnectionClosed(status, this);
try {
this.handler.afterConnectionClosed(status, this);
}
finally {
this.handlerProvider.destroy(this.handler);
}
}
}
}

3
spring-websocket/src/main/java/org/springframework/sockjs/SockJsSessionFactory.java

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package org.springframework.sockjs;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
@ -28,6 +29,6 @@ import org.springframework.websocket.WebSocketSession; @@ -28,6 +29,6 @@ import org.springframework.websocket.WebSocketSession;
*/
public interface SockJsSessionFactory<S extends WebSocketSession>{
S createSession(String sessionId, WebSocketHandler webSocketHandler);
S createSession(String sessionId, HandlerProvider<WebSocketHandler> handler);
}

5
spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractServerSockJsSession.java

@ -25,6 +25,7 @@ import java.util.concurrent.ScheduledFuture; @@ -25,6 +25,7 @@ import java.util.concurrent.ScheduledFuture;
import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketMessage;
@ -45,9 +46,9 @@ public abstract class AbstractServerSockJsSession extends AbstractSockJsSession @@ -45,9 +46,9 @@ public abstract class AbstractServerSockJsSession extends AbstractSockJsSession
public AbstractServerSockJsSession(String sessionId, SockJsConfiguration config,
WebSocketHandler webSocketHandler) {
HandlerProvider<WebSocketHandler> handler) {
super(sessionId, webSocketHandler);
super(sessionId, handler);
this.sockJsConfig = config;
}

11
spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractSockJsService.java

@ -39,6 +39,7 @@ import org.springframework.util.CollectionUtils; @@ -39,6 +39,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -218,7 +219,7 @@ public abstract class AbstractSockJsService @@ -218,7 +219,7 @@ public abstract class AbstractSockJsService
* @throws Exception
*/
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
String sockJsPath, WebSocketHandler webSocketHandler) throws Exception {
String sockJsPath, HandlerProvider<WebSocketHandler> handler) throws Exception {
logger.debug(request.getMethod() + " [" + sockJsPath + "]");
@ -244,7 +245,7 @@ public abstract class AbstractSockJsService @@ -244,7 +245,7 @@ public abstract class AbstractSockJsService
return;
}
else if (sockJsPath.equals("/websocket")) {
handleRawWebSocketRequest(request, response, webSocketHandler);
handleRawWebSocketRequest(request, response, handler);
return;
}
@ -264,7 +265,7 @@ public abstract class AbstractSockJsService @@ -264,7 +265,7 @@ public abstract class AbstractSockJsService
return;
}
handleTransportRequest(request, response, sessionId, TransportType.fromValue(transport), webSocketHandler);
handleTransportRequest(request, response, sessionId, TransportType.fromValue(transport), handler);
}
finally {
response.flush();
@ -272,10 +273,10 @@ public abstract class AbstractSockJsService @@ -272,10 +273,10 @@ public abstract class AbstractSockJsService
}
protected abstract void handleRawWebSocketRequest(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler) throws Exception;
HandlerProvider<WebSocketHandler> handler) throws Exception;
protected abstract void handleTransportRequest(ServerHttpRequest request, ServerHttpResponse response,
String sessionId, TransportType transportType, WebSocketHandler webSocketHandler) throws Exception;
String sessionId, TransportType transportType, HandlerProvider<WebSocketHandler> handler) throws Exception;
protected boolean validateRequest(String serverId, String sessionId, String transport) {

3
spring-websocket/src/main/java/org/springframework/sockjs/server/SockJsService.java

@ -18,6 +18,7 @@ package org.springframework.sockjs.server; @@ -18,6 +18,7 @@ package org.springframework.sockjs.server;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -30,6 +31,6 @@ public interface SockJsService { @@ -30,6 +31,6 @@ public interface SockJsService {
void handleRequest(ServerHttpRequest request, ServerHttpResponse response, String sockJsPath,
WebSocketHandler webSocketHandler) throws Exception;
HandlerProvider<WebSocketHandler> handler) throws Exception;
}

3
spring-websocket/src/main/java/org/springframework/sockjs/server/TransportHandler.java

@ -18,6 +18,7 @@ package org.springframework.sockjs.server; @@ -18,6 +18,7 @@ package org.springframework.sockjs.server;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -31,6 +32,6 @@ public interface TransportHandler { @@ -31,6 +32,6 @@ public interface TransportHandler {
TransportType getTransportType();
void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler, AbstractSockJsSession session) throws Exception;
HandlerProvider<WebSocketHandler> handler, AbstractSockJsSession session) throws Exception;
}

18
spring-websocket/src/main/java/org/springframework/sockjs/server/support/DefaultSockJsService.java

@ -21,7 +21,6 @@ import java.util.List; @@ -21,7 +21,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.Cookie;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
@ -43,6 +42,7 @@ import org.springframework.sockjs.server.transport.XhrPollingTransportHandler; @@ -43,6 +42,7 @@ import org.springframework.sockjs.server.transport.XhrPollingTransportHandler;
import org.springframework.sockjs.server.transport.XhrStreamingTransportHandler;
import org.springframework.sockjs.server.transport.XhrTransportHandler;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.server.DefaultHandshakeHandler;
import org.springframework.websocket.server.HandshakeHandler;
@ -54,7 +54,7 @@ import org.springframework.websocket.server.HandshakeHandler; @@ -54,7 +54,7 @@ import org.springframework.websocket.server.HandshakeHandler;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class DefaultSockJsService extends AbstractSockJsService implements InitializingBean {
public class DefaultSockJsService extends AbstractSockJsService {
private final Map<TransportType, TransportHandler> transportHandlers = new HashMap<TransportType, TransportHandler>();
@ -157,13 +157,13 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi @@ -157,13 +157,13 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi
@Override
protected void handleRawWebSocketRequest(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler) throws Exception {
HandlerProvider<WebSocketHandler> handler) throws Exception {
if (isWebSocketEnabled()) {
TransportHandler transportHandler = this.transportHandlers.get(TransportType.WEBSOCKET);
if (transportHandler != null) {
if (transportHandler instanceof HandshakeHandler) {
((HandshakeHandler) transportHandler).doHandshake(request, response, webSocketHandler);
((HandshakeHandler) transportHandler).doHandshake(request, response, handler);
return;
}
}
@ -174,7 +174,7 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi @@ -174,7 +174,7 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi
@Override
protected void handleTransportRequest(ServerHttpRequest request, ServerHttpResponse response,
String sessionId, TransportType transportType, WebSocketHandler webSocketHandler) throws Exception {
String sessionId, TransportType transportType, HandlerProvider<WebSocketHandler> handler) throws Exception {
TransportHandler transportHandler = this.transportHandlers.get(transportType);
@ -201,7 +201,7 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi @@ -201,7 +201,7 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi
return;
}
AbstractSockJsSession session = getSockJsSession(sessionId, webSocketHandler, transportHandler);
AbstractSockJsSession session = getSockJsSession(sessionId, handler, transportHandler);
if (session != null) {
if (transportType.setsNoCacheHeader()) {
@ -220,10 +220,10 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi @@ -220,10 +220,10 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi
}
}
transportHandler.handleRequest(request, response, webSocketHandler, session);
transportHandler.handleRequest(request, response, handler, session);
}
public AbstractSockJsSession getSockJsSession(String sessionId, WebSocketHandler webSocketHandler,
public AbstractSockJsSession getSockJsSession(String sessionId, HandlerProvider<WebSocketHandler> handler,
TransportHandler transportHandler) {
AbstractSockJsSession session = this.sessions.get(sessionId);
@ -240,7 +240,7 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi @@ -240,7 +240,7 @@ public class DefaultSockJsService extends AbstractSockJsService implements Initi
return session;
}
logger.debug("Creating new session with session id \"" + sessionId + "\"");
session = (AbstractSockJsSession) sessionFactory.createSession(sessionId, webSocketHandler);
session = (AbstractSockJsSession) sessionFactory.createSession(sessionId, handler);
this.sessions.put(sessionId, session);
return session;
}

26
spring-websocket/src/main/java/org/springframework/sockjs/server/support/SockJsHttpRequestHandler.java

@ -22,9 +22,6 @@ import javax.servlet.ServletException; @@ -22,9 +22,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.http.server.AsyncServletServerHttpRequest;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
@ -36,6 +33,7 @@ import org.springframework.web.util.NestedServletException; @@ -36,6 +33,7 @@ import org.springframework.web.util.NestedServletException;
import org.springframework.web.util.UrlPathHelper;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -43,7 +41,7 @@ import org.springframework.websocket.WebSocketHandler; @@ -43,7 +41,7 @@ import org.springframework.websocket.WebSocketHandler;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactoryAware {
public class SockJsHttpRequestHandler implements HttpRequestHandler {
private final String prefix;
@ -61,15 +59,15 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory @@ -61,15 +59,15 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory
* that begins with the specified prefix will be handled by this service. In a
* Servlet container this is the path within the current servlet mapping.
*/
public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService, WebSocketHandler webSocketHandler) {
public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService, WebSocketHandler handler) {
Assert.hasText(prefix, "prefix is required");
Assert.notNull(sockJsService, "sockJsService is required");
Assert.notNull(webSocketHandler, "webSocketHandler is required");
Assert.notNull(handler, "webSocketHandler is required");
this.prefix = prefix;
this.sockJsService = sockJsService;
this.handlerProvider = new HandlerProvider<WebSocketHandler>(webSocketHandler);
this.handlerProvider = new SimpleHandlerProvider<WebSocketHandler>(handler);
}
/**
@ -80,15 +78,15 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory @@ -80,15 +78,15 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory
* Servlet container this is the path within the current servlet mapping.
*/
public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService,
Class<? extends WebSocketHandler> webSocketHandlerClass) {
HandlerProvider<WebSocketHandler> handlerProvider) {
Assert.hasText(prefix, "prefix is required");
Assert.notNull(sockJsService, "sockJsService is required");
Assert.notNull(webSocketHandlerClass, "webSocketHandlerClass is required");
Assert.notNull(handlerProvider, "handlerProvider is required");
this.prefix = prefix;
this.sockJsService = sockJsService;
this.handlerProvider = new HandlerProvider<WebSocketHandler>(webSocketHandlerClass);
this.handlerProvider = handlerProvider;
}
public String getPrefix() {
@ -99,11 +97,6 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory @@ -99,11 +97,6 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory
return this.prefix + "/**";
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.handlerProvider.setBeanFactory(beanFactory);
}
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
@ -119,8 +112,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory @@ -119,8 +112,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler, BeanFactory
ServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
try {
WebSocketHandler webSocketHandler = this.handlerProvider.getHandler();
this.sockJsService.handleRequest(httpRequest, httpResponse, sockJsPath, webSocketHandler);
this.sockJsService.handleRequest(httpRequest, httpResponse, sockJsPath, this.handlerProvider);
}
catch (Exception ex) {
// TODO

3
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpReceivingTransportHandler.java

@ -27,6 +27,7 @@ import org.springframework.http.server.ServerHttpRequest; @@ -27,6 +27,7 @@ import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.AbstractSockJsSession;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import com.fasterxml.jackson.databind.JsonMappingException;
@ -53,7 +54,7 @@ public abstract class AbstractHttpReceivingTransportHandler implements Transport @@ -53,7 +54,7 @@ public abstract class AbstractHttpReceivingTransportHandler implements Transport
@Override
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler, AbstractSockJsSession session) throws Exception {
HandlerProvider<WebSocketHandler> webSocketHandler, AbstractSockJsSession session) throws Exception {
if (session == null) {
response.setStatusCode(HttpStatus.NOT_FOUND);

3
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpSendingTransportHandler.java

@ -28,6 +28,7 @@ import org.springframework.sockjs.server.ConfigurableTransportHandler; @@ -28,6 +28,7 @@ import org.springframework.sockjs.server.ConfigurableTransportHandler;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -55,7 +56,7 @@ public abstract class AbstractHttpSendingTransportHandler @@ -55,7 +56,7 @@ public abstract class AbstractHttpSendingTransportHandler
@Override
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler, AbstractSockJsSession session) throws Exception {
HandlerProvider<WebSocketHandler> webSocketHandler, AbstractSockJsSession session) throws Exception {
// Set content type before writing
response.getHeaders().setContentType(getContentType());

5
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpServerSockJsSession.java

@ -29,6 +29,7 @@ import org.springframework.sockjs.server.SockJsFrame.FrameFormat; @@ -29,6 +29,7 @@ import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
/**
@ -49,9 +50,9 @@ public abstract class AbstractHttpServerSockJsSession extends AbstractServerSock @@ -49,9 +50,9 @@ public abstract class AbstractHttpServerSockJsSession extends AbstractServerSock
public AbstractHttpServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig,
WebSocketHandler webSocketHandler) {
HandlerProvider<WebSocketHandler> handler) {
super(sessionId, sockJsConfig, webSocketHandler);
super(sessionId, sockJsConfig, handler);
}
public void setFrameFormat(FrameFormat frameFormat) {

5
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractStreamingTransportHandler.java

@ -20,6 +20,7 @@ import java.io.IOException; @@ -20,6 +20,7 @@ import java.io.IOException;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -33,9 +34,9 @@ public abstract class AbstractStreamingTransportHandler extends AbstractHttpSend @@ -33,9 +34,9 @@ public abstract class AbstractStreamingTransportHandler extends AbstractHttpSend
@Override
public StreamingServerSockJsSession createSession(String sessionId, WebSocketHandler webSocketHandler) {
public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), webSocketHandler);
return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler);
}
@Override

5
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/JsonpPollingTransportHandler.java

@ -27,6 +27,7 @@ import org.springframework.sockjs.server.TransportType; @@ -27,6 +27,7 @@ import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.util.JavaScriptUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -50,9 +51,9 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa @@ -50,9 +51,9 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa
}
@Override
public PollingServerSockJsSession createSession(String sessionId, WebSocketHandler webSocketHandler) {
public PollingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new PollingServerSockJsSession(sessionId, getSockJsConfig(), webSocketHandler);
return new PollingServerSockJsSession(sessionId, getSockJsConfig(), handler);
}
@Override

5
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/PollingServerSockJsSession.java

@ -17,15 +17,16 @@ package org.springframework.sockjs.server.transport; @@ -17,15 +17,16 @@ package org.springframework.sockjs.server.transport;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
public class PollingServerSockJsSession extends AbstractHttpServerSockJsSession {
public PollingServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig,
WebSocketHandler webSocketHandler) {
HandlerProvider<WebSocketHandler> handler) {
super(sessionId, sockJsConfig, webSocketHandler);
super(sessionId, sockJsConfig, handler);
}
@Override

40
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/SockJsWebSocketHandler.java

@ -17,8 +17,6 @@ @@ -17,8 +17,6 @@
package org.springframework.sockjs.server.transport;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -29,6 +27,7 @@ import org.springframework.sockjs.server.SockJsFrame; @@ -29,6 +27,7 @@ import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.TextMessageHandler;
import org.springframework.websocket.WebSocketHandler;
@ -38,8 +37,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; @@ -38,8 +37,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
/**
* A SockJS implementation of {@link WebSocketHandler}. Delegates messages to and from a
* {@link SockJsHandler} and adds SockJS message framing.
* A wrapper around a {@link WebSocketHandler} instance that parses and adds SockJS
* messages frames as well as sends SockJS heartbeat messages.
*
* @author Rossen Stoyanchev
* @since 4.0
@ -50,34 +49,28 @@ public class SockJsWebSocketHandler implements TextMessageHandler { @@ -50,34 +49,28 @@ public class SockJsWebSocketHandler implements TextMessageHandler {
private final SockJsConfiguration sockJsConfig;
private final WebSocketHandler webSocketHandler;
private final HandlerProvider<WebSocketHandler> handlerProvider;
private final Map<WebSocketSession, AbstractSockJsSession> sessions =
new ConcurrentHashMap<WebSocketSession, AbstractSockJsSession>();
private AbstractSockJsSession session;
// TODO: JSON library used must be configurable
private final ObjectMapper objectMapper = new ObjectMapper();
public SockJsWebSocketHandler(SockJsConfiguration sockJsConfig, WebSocketHandler webSocketHandler) {
Assert.notNull(sockJsConfig, "sockJsConfig is required");
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.sockJsConfig = sockJsConfig;
this.webSocketHandler = webSocketHandler;
public SockJsWebSocketHandler(SockJsConfiguration config, HandlerProvider<WebSocketHandler> handlerProvider) {
Assert.notNull(config, "sockJsConfig is required");
Assert.notNull(handlerProvider, "handlerProvider is required");
this.sockJsConfig = config;
this.handlerProvider = handlerProvider;
}
protected SockJsConfiguration getSockJsConfig() {
return this.sockJsConfig;
}
protected AbstractSockJsSession getSockJsSession(WebSocketSession wsSession) {
return this.sessions.get(wsSession);
}
@Override
public void afterConnectionEstablished(WebSocketSession wsSession) throws Exception {
AbstractSockJsSession session = new WebSocketServerSockJsSession(wsSession, getSockJsConfig());
this.sessions.put(wsSession, session);
this.session = new WebSocketServerSockJsSession(wsSession, getSockJsConfig());
}
@Override
@ -89,8 +82,7 @@ public class SockJsWebSocketHandler implements TextMessageHandler { @@ -89,8 +82,7 @@ public class SockJsWebSocketHandler implements TextMessageHandler {
}
try {
String[] messages = this.objectMapper.readValue(payload, String[].class);
AbstractSockJsSession session = getSockJsSession(wsSession);
session.delegateMessages(messages);
this.session.delegateMessages(messages);
}
catch (IOException e) {
logger.error("Broken data received. Terminating WebSocket connection abruptly", e);
@ -100,14 +92,12 @@ public class SockJsWebSocketHandler implements TextMessageHandler { @@ -100,14 +92,12 @@ public class SockJsWebSocketHandler implements TextMessageHandler {
@Override
public void afterConnectionClosed(CloseStatus status, WebSocketSession wsSession) throws Exception {
AbstractSockJsSession session = this.sessions.remove(wsSession);
session.delegateConnectionClosed(status);
this.session.delegateConnectionClosed(status);
}
@Override
public void handleError(Throwable exception, WebSocketSession webSocketSession) {
AbstractSockJsSession session = getSockJsSession(webSocketSession);
session.delegateError(exception);
this.session.delegateError(exception);
}
private static String getSockJsSessionId(WebSocketSession wsSession) {
@ -127,7 +117,7 @@ public class SockJsWebSocketHandler implements TextMessageHandler { @@ -127,7 +117,7 @@ public class SockJsWebSocketHandler implements TextMessageHandler {
public WebSocketServerSockJsSession(WebSocketSession wsSession, SockJsConfiguration sockJsConfig)
throws Exception {
super(getSockJsSessionId(wsSession), sockJsConfig, SockJsWebSocketHandler.this.webSocketHandler);
super(getSockJsSessionId(wsSession), sockJsConfig, SockJsWebSocketHandler.this.handlerProvider);
this.wsSession = wsSession;
TextMessage message = new TextMessage(SockJsFrame.openFrame().getContent());
this.wsSession.sendMessage(message);

5
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/StreamingServerSockJsSession.java

@ -20,6 +20,7 @@ import java.io.IOException; @@ -20,6 +20,7 @@ import java.io.IOException;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.SockJsFrame;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -29,9 +30,9 @@ public class StreamingServerSockJsSession extends AbstractHttpServerSockJsSessio @@ -29,9 +30,9 @@ public class StreamingServerSockJsSession extends AbstractHttpServerSockJsSessio
public StreamingServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig,
WebSocketHandler webSocketHandler) {
HandlerProvider<WebSocketHandler> handler) {
super(sessionId, sockJsConfig, webSocketHandler);
super(sessionId, sockJsConfig, handler);
}
protected void flushCache() throws Exception {

19
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/WebSocketTransportHandler.java

@ -24,8 +24,10 @@ import org.springframework.sockjs.server.SockJsConfiguration; @@ -24,8 +24,10 @@ import org.springframework.sockjs.server.SockJsConfiguration;
import org.springframework.sockjs.server.TransportHandler;
import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.server.HandshakeHandler;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -60,26 +62,19 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler, @@ -60,26 +62,19 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler,
@Override
public void handleRequest(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler, AbstractSockJsSession session) throws Exception {
HandlerProvider<WebSocketHandler> handler, AbstractSockJsSession session) throws Exception {
this.handshakeHandler.doHandshake(request, response, adaptSockJsHandler(webSocketHandler));
}
/**
* Adapt the {@link SockJsHandler} to the {@link WebSocketHandler} contract for
* exchanging SockJS message over WebSocket.
*/
protected WebSocketHandler adaptSockJsHandler(WebSocketHandler handler) {
return new SockJsWebSocketHandler(this.sockJsConfig, handler);
WebSocketHandler sockJsWrapper = new SockJsWebSocketHandler(this.sockJsConfig, handler);
this.handshakeHandler.doHandshake(request, response, new SimpleHandlerProvider<WebSocketHandler>(sockJsWrapper));
}
// HandshakeHandler methods
@Override
public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler) throws Exception {
HandlerProvider<WebSocketHandler> handler) throws Exception {
return this.handshakeHandler.doHandshake(request, response, webSocketHandler);
return this.handshakeHandler.doHandshake(request, response, handler);
}
}

5
spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrPollingTransportHandler.java

@ -23,6 +23,7 @@ import org.springframework.sockjs.server.SockJsFrame.DefaultFrameFormat; @@ -23,6 +23,7 @@ import org.springframework.sockjs.server.SockJsFrame.DefaultFrameFormat;
import org.springframework.sockjs.server.SockJsFrame.FrameFormat;
import org.springframework.sockjs.server.TransportType;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -50,9 +51,9 @@ public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHand @@ -50,9 +51,9 @@ public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHand
return new DefaultFrameFormat("%s\n");
}
public PollingServerSockJsSession createSession(String sessionId, WebSocketHandler webSocketHandler) {
public PollingServerSockJsSession createSession(String sessionId, HandlerProvider<WebSocketHandler> handler) {
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
return new PollingServerSockJsSession(sessionId, getSockJsConfig(), webSocketHandler);
return new PollingServerSockJsSession(sessionId, getSockJsConfig(), handler);
}
}

94
spring-websocket/src/main/java/org/springframework/websocket/HandlerProvider.java

@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@ -13,82 +13,36 @@ @@ -13,82 +13,36 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* A strategy for obtaining a handler instance that is scoped to external lifecycle events
* such as the opening and closing of a WebSocket connection.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class HandlerProvider<T> implements BeanFactoryAware {
private Log logger = LogFactory.getLog(this.getClass());
private final T handlerBean;
private final Class<? extends T> handlerClass;
private AutowireCapableBeanFactory beanFactory;
public HandlerProvider(T handlerBean) {
Assert.notNull(handlerBean, "handlerBean is required");
this.handlerBean = handlerBean;
this.handlerClass = null;
}
public HandlerProvider(Class<? extends T> handlerClass) {
Assert.notNull(handlerClass, "handlerClass is required");
this.handlerBean = null;
this.handlerClass = handlerClass;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof AutowireCapableBeanFactory) {
this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
}
}
public void setLogger(Log logger) {
this.logger = logger;
}
public boolean isSingleton() {
return (this.handlerBean != null);
}
@SuppressWarnings("unchecked")
public Class<? extends T> getHandlerType() {
if (this.handlerClass != null) {
return this.handlerClass;
}
return (Class<? extends T>) ClassUtils.getUserClass(this.handlerBean.getClass());
}
public T getHandler() {
if (this.handlerBean != null) {
if (logger != null && logger.isTraceEnabled()) {
logger.trace("Returning handler singleton " + this.handlerBean);
}
return this.handlerBean;
}
Assert.isTrue(this.beanFactory != null, "BeanFactory is required to initialize handler instances.");
if (logger != null && logger.isTraceEnabled()) {
logger.trace("Creating handler of type " + this.handlerClass);
}
return this.beanFactory.createBean(this.handlerClass);
}
public interface HandlerProvider<T> {
/**
* Whether the provided handler is a shared instance or not.
*/
boolean isSingleton();
/**
* The type of handler provided.
*/
Class<?> getHandlerType();
/**
* Obtain the handler instance, either shared or created every time.
*/
T getHandler();
/**
* Callback to destroy a previously created handler instance if it is not shared.
*/
void destroy(T handler);
}

10
spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketClient.java

@ -18,6 +18,7 @@ package org.springframework.websocket.client; @@ -18,6 +18,7 @@ package org.springframework.websocket.client;
import java.net.URI;
import org.springframework.http.HttpHeaders;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
@ -36,13 +37,10 @@ import org.springframework.websocket.WebSocketSession; @@ -36,13 +37,10 @@ import org.springframework.websocket.WebSocketSession;
public interface WebSocketClient {
WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate, Object... uriVariables)
throws WebSocketConnectFailureException;
WebSocketSession doHandshake(WebSocketHandler handler, URI uri)
throws WebSocketConnectFailureException;
WebSocketSession doHandshake(HandlerProvider<WebSocketHandler> handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException;
WebSocketSession doHandshake(WebSocketHandler handler, HttpHeaders headers, URI uri)
WebSocketSession doHandshake(HandlerProvider<WebSocketHandler> handler, HttpHeaders headers, URI uri)
throws WebSocketConnectFailureException;
}

16
spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketConnectionManager.java

@ -21,6 +21,7 @@ import org.springframework.http.HttpHeaders; @@ -21,6 +21,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -32,7 +33,7 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag @@ -32,7 +33,7 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag
private final WebSocketClient client;
private final HandlerProvider<WebSocketHandler> webSocketHandlerProvider;
private final HandlerProvider<WebSocketHandler> handlerProvider;
private WebSocketSession webSocketSession;
@ -43,8 +44,16 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag @@ -43,8 +44,16 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag
WebSocketHandler webSocketHandler, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.webSocketHandlerProvider = new HandlerProvider<WebSocketHandler>(webSocketHandler);
this.client = webSocketClient;
this.handlerProvider = new SimpleHandlerProvider<WebSocketHandler>(webSocketHandler);
}
public WebSocketConnectionManager(WebSocketClient webSocketClient,
HandlerProvider<WebSocketHandler> handlerProvider, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.client = webSocketClient;
this.handlerProvider = handlerProvider;
}
public void setSubProtocols(List<String> subProtocols) {
@ -57,10 +66,9 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag @@ -57,10 +66,9 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag
@Override
protected void openConnection() throws Exception {
WebSocketHandler webSocketHandler = this.webSocketHandlerProvider.getHandler();
HttpHeaders headers = new HttpHeaders();
headers.setSecWebSocketProtocol(this.subProtocols);
this.webSocketSession = this.client.doHandshake(webSocketHandler, headers, getUri());
this.webSocketSession = this.client.doHandshake(this.handlerProvider, headers, getUri());
}
@Override

19
spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/AnnotatedEndpointConnectionManager.java

@ -22,6 +22,8 @@ import org.springframework.beans.BeansException; @@ -22,6 +22,8 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.support.BeanCreatingHandlerProvider;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -32,28 +34,29 @@ import org.springframework.websocket.HandlerProvider; @@ -32,28 +34,29 @@ import org.springframework.websocket.HandlerProvider;
public class AnnotatedEndpointConnectionManager extends EndpointConnectionManagerSupport
implements BeanFactoryAware {
private final HandlerProvider<Object> endpointProvider;
private final HandlerProvider<Object> handlerProvider;
public AnnotatedEndpointConnectionManager(Class<?> endpointClass, String uriTemplate, Object... uriVariables) {
public AnnotatedEndpointConnectionManager(Object endpointBean, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.endpointProvider = new HandlerProvider<Object>(endpointClass);
this.handlerProvider = new SimpleHandlerProvider<Object>(endpointBean);
}
public AnnotatedEndpointConnectionManager(Object endpointBean, String uriTemplate, Object... uriVariables) {
public AnnotatedEndpointConnectionManager(Class<?> endpointClass, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
this.endpointProvider = new HandlerProvider<Object>(endpointBean);
this.handlerProvider = new BeanCreatingHandlerProvider<Object>(endpointClass);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.endpointProvider.setBeanFactory(beanFactory);
if (this.handlerProvider instanceof BeanFactoryAware) {
((BeanFactoryAware) this.handlerProvider).setBeanFactory(beanFactory);
}
}
@Override
protected void openConnection() throws Exception {
Object endpoint = this.endpointProvider.getHandler();
Object endpoint = this.handlerProvider.getHandler();
Session session = getWebSocketContainer().connectToServer(endpoint, getUri());
updateSession(session);
}

14
spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManager.java

@ -32,6 +32,8 @@ import org.springframework.beans.factory.BeanFactory; @@ -32,6 +32,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.support.BeanCreatingHandlerProvider;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -43,19 +45,19 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport @@ -43,19 +45,19 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport
private final ClientEndpointConfig.Builder configBuilder = ClientEndpointConfig.Builder.create();
private final HandlerProvider<Endpoint> endpointProvider;
private final HandlerProvider<Endpoint> handlerProvider;
public EndpointConnectionManager(Endpoint endpointBean, String uriTemplate, Object... uriVariables) {
super(uriTemplate, uriVariables);
Assert.notNull(endpointBean, "endpointBean is required");
this.endpointProvider = new HandlerProvider<Endpoint>(endpointBean);
this.handlerProvider = new SimpleHandlerProvider<Endpoint>(endpointBean);
}
public EndpointConnectionManager(Class<? extends Endpoint> endpointClass, String uriTemplate, Object... uriVars) {
super(uriTemplate, uriVars);
Assert.notNull(endpointClass, "endpointClass is required");
this.endpointProvider = new HandlerProvider<Endpoint>(endpointClass);
this.handlerProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
}
public void setSubProtocols(String... subprotocols) {
@ -80,12 +82,14 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport @@ -80,12 +82,14 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.endpointProvider.setBeanFactory(beanFactory);
if (this.handlerProvider instanceof BeanFactoryAware) {
((BeanFactoryAware) this.handlerProvider).setBeanFactory(beanFactory);
}
}
@Override
protected void openConnection() throws Exception {
Endpoint endpoint = this.endpointProvider.getHandler();
Endpoint endpoint = this.handlerProvider.getHandler();
ClientEndpointConfig endpointConfig = this.configBuilder.build();
Session session = getWebSocketContainer().connectToServer(endpoint, endpointConfig, getUri());
updateSession(session);

15
spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/StandardWebSocketClient.java

@ -31,6 +31,7 @@ import javax.websocket.WebSocketContainer; @@ -31,6 +31,7 @@ import javax.websocket.WebSocketContainer;
import org.springframework.http.HttpHeaders;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
import org.springframework.websocket.client.WebSocketClient;
@ -40,6 +41,7 @@ import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint; @@ -40,6 +41,7 @@ import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
/**
* A standard Java {@link WebSocketClient}.
*
* @author Rossen Stoyanchev
* @since 4.0
@ -57,21 +59,16 @@ public class StandardWebSocketClient implements WebSocketClient { @@ -57,21 +59,16 @@ public class StandardWebSocketClient implements WebSocketClient {
this.webSocketContainer = container;
}
public WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate,
Object... uriVariables) throws WebSocketConnectFailureException {
public WebSocketSession doHandshake(HandlerProvider<WebSocketHandler> handler,
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException {
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri();
return doHandshake(handler, uri);
}
@Override
public WebSocketSession doHandshake(WebSocketHandler handler, URI uri) throws WebSocketConnectFailureException {
return doHandshake(handler, null, uri);
}
@Override
public WebSocketSession doHandshake(WebSocketHandler handler, final HttpHeaders httpHeaders, URI uri)
throws WebSocketConnectFailureException {
public WebSocketSession doHandshake(HandlerProvider<WebSocketHandler> handler,
final HttpHeaders httpHeaders, URI uri) throws WebSocketConnectFailureException {
Endpoint endpoint = new WebSocketHandlerEndpoint(handler);

69
spring-websocket/src/main/java/org/springframework/websocket/endpoint/WebSocketHandlerEndpoint.java

@ -16,9 +16,6 @@ @@ -16,9 +16,6 @@
package org.springframework.websocket.endpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
@ -27,14 +24,15 @@ import javax.websocket.MessageHandler; @@ -27,14 +24,15 @@ import javax.websocket.MessageHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.BinaryMessage;
import org.springframework.websocket.BinaryMessageHandler;
import org.springframework.websocket.CloseStatus;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.PartialMessageHandler;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
import org.springframework.websocket.TextMessage;
import org.springframework.websocket.TextMessageHandler;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.WebSocketSession;
/**
@ -47,14 +45,17 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -47,14 +45,17 @@ public class WebSocketHandlerEndpoint extends Endpoint {
private static Log logger = LogFactory.getLog(WebSocketHandlerEndpoint.class);
private final WebSocketHandler webSocketHandler;
private final HandlerProvider<WebSocketHandler> handlerProvider;
private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<String, WebSocketSession>();
private final WebSocketHandler handler;
private WebSocketSession webSocketSession;
public WebSocketHandlerEndpoint(WebSocketHandler handler) {
Assert.notNull(handler, "webSocketHandler is required");
this.webSocketHandler = handler;
public WebSocketHandlerEndpoint(HandlerProvider<WebSocketHandler> handlerProvider) {
Assert.notNull(handlerProvider, "handlerProvider is required");
this.handlerProvider = handlerProvider;
this.handler = handlerProvider.getHandler();
}
@Override
@ -63,10 +64,9 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -63,10 +64,9 @@ public class WebSocketHandlerEndpoint extends Endpoint {
logger.debug("Client connected, WebSocket session id=" + session.getId() + ", uri=" + session.getRequestURI());
}
try {
WebSocketSession webSocketSession = new StandardWebSocketSession(session);
this.sessions.put(session.getId(), webSocketSession);
this.webSocketSession = new StandardWebSocketSession(session);
if (this.webSocketHandler instanceof TextMessageHandler) {
if (this.handler instanceof TextMessageHandler) {
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String message) {
@ -74,8 +74,8 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -74,8 +74,8 @@ public class WebSocketHandlerEndpoint extends Endpoint {
}
});
}
else if (this.webSocketHandler instanceof BinaryMessageHandler) {
if (this.webSocketHandler instanceof PartialMessageHandler) {
else if (this.handler instanceof BinaryMessageHandler) {
if (this.handler instanceof PartialMessageHandler) {
session.addMessageHandler(new MessageHandler.Partial<byte[]>() {
@Override
public void onMessage(byte[] messagePart, boolean isLast) {
@ -93,10 +93,10 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -93,10 +93,10 @@ public class WebSocketHandlerEndpoint extends Endpoint {
}
}
else {
logger.warn("WebSocketHandler handles neither text nor binary messages: " + this.webSocketHandler);
logger.warn("WebSocketHandler handles neither text nor binary messages: " + this.handler);
}
this.webSocketHandler.afterConnectionEstablished(webSocketSession);
this.handler.afterConnectionEstablished(this.webSocketSession);
}
catch (Throwable ex) {
// TODO
@ -108,11 +108,9 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -108,11 +108,9 @@ public class WebSocketHandlerEndpoint extends Endpoint {
if (logger.isTraceEnabled()) {
logger.trace("Received message for WebSocket session id=" + session.getId() + ": " + message);
}
WebSocketSession wsSession = getWebSocketSession(session);
Assert.notNull(wsSession, "WebSocketSession not found");
try {
TextMessage textMessage = new TextMessage(message);
((TextMessageHandler) webSocketHandler).handleTextMessage(textMessage, wsSession);
((TextMessageHandler) handler).handleTextMessage(textMessage, this.webSocketSession);
}
catch (Throwable ex) {
// TODO
@ -124,11 +122,9 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -124,11 +122,9 @@ public class WebSocketHandlerEndpoint extends Endpoint {
if (logger.isTraceEnabled()) {
logger.trace("Received binary data for WebSocket session id=" + session.getId());
}
WebSocketSession wsSession = getWebSocketSession(session);
Assert.notNull(wsSession, "WebSocketSession not found");
try {
BinaryMessage binaryMessage = new BinaryMessage(message, isLast);
((BinaryMessageHandler) webSocketHandler).handleBinaryMessage(binaryMessage, wsSession);
((BinaryMessageHandler) handler).handleBinaryMessage(binaryMessage, this.webSocketSession);
}
catch (Throwable ex) {
// TODO
@ -142,32 +138,23 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -142,32 +138,23 @@ public class WebSocketHandlerEndpoint extends Endpoint {
logger.debug("Client disconnected, WebSocket session id=" + session.getId() + ", " + reason);
}
try {
WebSocketSession wsSession = this.sessions.remove(session.getId());
if (wsSession != null) {
CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase());
this.webSocketHandler.afterConnectionClosed(closeStatus, wsSession);
}
else {
Assert.notNull(wsSession, "No WebSocket session");
}
CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase());
this.handler.afterConnectionClosed(closeStatus, this.webSocketSession);
}
catch (Throwable ex) {
// TODO
logger.error("Error while processing session closing", ex);
}
finally {
this.handlerProvider.destroy(this.handler);
}
}
@Override
public void onError(javax.websocket.Session session, Throwable exception) {
logger.error("Error for WebSocket session id=" + session.getId(), exception);
try {
WebSocketSession wsSession = getWebSocketSession(session);
if (wsSession != null) {
this.webSocketHandler.handleError(exception, wsSession);
}
else {
logger.warn("WebSocketSession not found. Perhaps onError was called after onClose?");
}
this.handler.handleError(exception, this.webSocketSession);
}
catch (Throwable ex) {
// TODO
@ -175,8 +162,4 @@ public class WebSocketHandlerEndpoint extends Endpoint { @@ -175,8 +162,4 @@ public class WebSocketHandlerEndpoint extends Endpoint {
}
}
private WebSocketSession getWebSocketSession(javax.websocket.Session session) {
return this.sessions.get(session.getId());
}
}

7
spring-websocket/src/main/java/org/springframework/websocket/server/DefaultHandshakeHandler.java

@ -35,6 +35,7 @@ import org.springframework.http.server.ServerHttpRequest; @@ -35,6 +35,7 @@ import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -87,7 +88,7 @@ public class DefaultHandshakeHandler implements HandshakeHandler { @@ -87,7 +88,7 @@ public class DefaultHandshakeHandler implements HandshakeHandler {
@Override
public final boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
WebSocketHandler webSocketHandler) throws Exception {
HandlerProvider<WebSocketHandler> handler) throws Exception {
logger.debug("Starting handshake for " + request.getURI());
@ -135,10 +136,10 @@ public class DefaultHandshakeHandler implements HandshakeHandler { @@ -135,10 +136,10 @@ public class DefaultHandshakeHandler implements HandshakeHandler {
response.flush();
if (logger.isTraceEnabled()) {
logger.trace("Upgrading with " + webSocketHandler);
logger.trace("Upgrading with " + handler);
}
this.requestUpgradeStrategy.upgrade(request, response, selectedProtocol, webSocketHandler);
this.requestUpgradeStrategy.upgrade(request, response, selectedProtocol, handler);
return true;
}

15
spring-websocket/src/main/java/org/springframework/websocket/server/HandshakeHandler.java

@ -18,6 +18,7 @@ package org.springframework.websocket.server; @@ -18,6 +18,7 @@ package org.springframework.websocket.server;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -29,16 +30,8 @@ import org.springframework.websocket.WebSocketHandler; @@ -29,16 +30,8 @@ import org.springframework.websocket.WebSocketHandler;
*/
public interface HandshakeHandler {
/**
*
* @param request the HTTP request
* @param response the HTTP response
* @param webSocketMessageHandler the handler to process WebSocket messages with
* @return a boolean indicating whether the handshake negotiation was successful
*
* @throws Exception
*/
boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler webSocketHandler)
throws Exception;
boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
HandlerProvider<WebSocketHandler> handler) throws Exception;
}

5
spring-websocket/src/main/java/org/springframework/websocket/server/RequestUpgradeStrategy.java

@ -18,6 +18,7 @@ package org.springframework.websocket.server; @@ -18,6 +18,7 @@ package org.springframework.websocket.server;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
@ -39,9 +40,9 @@ public interface RequestUpgradeStrategy { @@ -39,9 +40,9 @@ public interface RequestUpgradeStrategy {
* Perform runtime specific steps to complete the upgrade.
* Invoked only if the handshake is successful.
*
* @param webSocketHandler the handler for WebSocket messages
* @param handler the handler for WebSocket messages
*/
void upgrade(ServerHttpRequest request, ServerHttpResponse response, String selectedProtocol,
WebSocketHandler webSocketHandler) throws Exception;
HandlerProvider<WebSocketHandler> handler) throws Exception;
}

21
spring-websocket/src/main/java/org/springframework/websocket/server/endpoint/EndpointRegistration.java

@ -37,6 +37,8 @@ import org.springframework.beans.factory.BeanFactoryAware; @@ -37,6 +37,8 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
import org.springframework.websocket.support.BeanCreatingHandlerProvider;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -54,11 +56,9 @@ import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint; @@ -54,11 +56,9 @@ import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
*/
public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAware {
private static Log logger = LogFactory.getLog(EndpointRegistration.class);
private final String path;
private final HandlerProvider<Endpoint> endpointProvider;
private final HandlerProvider<Endpoint> handlerProvider;
private List<Class<? extends Encoder>> encoders = new ArrayList<Class<? extends Encoder>>();
@ -84,16 +84,14 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw @@ -84,16 +84,14 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
Assert.hasText(path, "path must not be empty");
Assert.notNull(endpointClass, "endpointClass is required");
this.path = path;
this.endpointProvider = new HandlerProvider<Endpoint>(endpointClass);
this.endpointProvider.setLogger(logger);
this.handlerProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
}
public EndpointRegistration(String path, Endpoint endpointBean) {
Assert.hasText(path, "path must not be empty");
Assert.notNull(endpointBean, "endpointBean is required");
this.path = path;
this.endpointProvider = new HandlerProvider<Endpoint>(endpointBean);
this.endpointProvider.setLogger(logger);
this.handlerProvider = new SimpleHandlerProvider<Endpoint>(endpointBean);
}
@Override
@ -102,12 +100,13 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw @@ -102,12 +100,13 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
}
@Override
@SuppressWarnings("unchecked")
public Class<? extends Endpoint> getEndpointClass() {
return this.endpointProvider.getHandlerType();
return (Class<? extends Endpoint>) this.handlerProvider.getHandlerType();
}
public Endpoint getEndpoint() {
return this.endpointProvider.getHandler();
return this.handlerProvider.getHandler();
}
public void setSubprotocols(List<String> subprotocols) {
@ -193,7 +192,9 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw @@ -193,7 +192,9 @@ public class EndpointRegistration implements ServerEndpointConfig, BeanFactoryAw
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.endpointProvider.setBeanFactory(beanFactory);
if (this.handlerProvider instanceof BeanFactoryAware) {
((BeanFactoryAware) this.handlerProvider).setBeanFactory(beanFactory);
}
}
}

88
spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointContainerFactoryBean.java

@ -1,88 +0,0 @@ @@ -1,88 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket.server.support;
import javax.websocket.WebSocketContainer;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
/**
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public abstract class AbstractEndpointContainerFactoryBean implements FactoryBean<WebSocketContainer>, InitializingBean {
private WebSocketContainer container;
public void setAsyncSendTimeout(long timeoutInMillis) {
this.container.setAsyncSendTimeout(timeoutInMillis);
}
public long getAsyncSendTimeout() {
return this.container.getDefaultAsyncSendTimeout();
}
public void setMaxSessionIdleTimeout(long timeoutInMillis) {
this.container.setDefaultMaxSessionIdleTimeout(timeoutInMillis);
}
public long getMaxSessionIdleTimeout() {
return this.container.getDefaultMaxSessionIdleTimeout();
}
public void setMaxTextMessageBufferSize(int bufferSize) {
this.container.setDefaultMaxTextMessageBufferSize(bufferSize);
}
public int getMaxTextMessageBufferSize() {
return this.container.getDefaultMaxTextMessageBufferSize();
}
public void setMaxBinaryMessageBufferSize(int bufferSize) {
this.container.setDefaultMaxBinaryMessageBufferSize(bufferSize);
}
public int getMaxBinaryMessageBufferSize() {
return this.container.getDefaultMaxBinaryMessageBufferSize();
}
@Override
public void afterPropertiesSet() throws Exception {
this.container = getContainer();
}
protected abstract WebSocketContainer getContainer();
@Override
public WebSocketContainer getObject() throws Exception {
return this.container;
}
@Override
public Class<?> getObjectType() {
return WebSocketContainer.class;
}
@Override
public boolean isSingleton() {
return true;
}
}

7
spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointUpgradeStrategy.java

@ -22,6 +22,7 @@ import org.apache.commons.logging.Log; @@ -22,6 +22,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.endpoint.WebSocketHandlerEndpoint;
import org.springframework.websocket.server.RequestUpgradeStrategy;
@ -41,12 +42,12 @@ public abstract class AbstractEndpointUpgradeStrategy implements RequestUpgradeS @@ -41,12 +42,12 @@ public abstract class AbstractEndpointUpgradeStrategy implements RequestUpgradeS
@Override
public void upgrade(ServerHttpRequest request, ServerHttpResponse response,
String protocol, WebSocketHandler webSocketHandler) throws Exception {
String protocol, HandlerProvider<WebSocketHandler> handler) throws Exception {
upgradeInternal(request, response, protocol, adaptWebSocketHandler(webSocketHandler));
upgradeInternal(request, response, protocol, adaptWebSocketHandler(handler));
}
protected Endpoint adaptWebSocketHandler(WebSocketHandler handler) {
protected Endpoint adaptWebSocketHandler(HandlerProvider<WebSocketHandler> handler) {
return new WebSocketHandlerEndpoint(handler);
}

22
spring-websocket/src/main/java/org/springframework/websocket/server/support/WebSocketHttpRequestHandler.java

@ -22,9 +22,6 @@ import javax.servlet.ServletException; @@ -22,9 +22,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
@ -36,6 +33,7 @@ import org.springframework.websocket.HandlerProvider; @@ -36,6 +33,7 @@ import org.springframework.websocket.HandlerProvider;
import org.springframework.websocket.WebSocketHandler;
import org.springframework.websocket.server.DefaultHandshakeHandler;
import org.springframework.websocket.server.HandshakeHandler;
import org.springframework.websocket.support.SimpleHandlerProvider;
/**
@ -44,7 +42,7 @@ import org.springframework.websocket.server.HandshakeHandler; @@ -44,7 +42,7 @@ import org.springframework.websocket.server.HandshakeHandler;
* @author Rossen Stoyanchev
* @since 4.0
*/
public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFactoryAware {
public class WebSocketHttpRequestHandler implements HttpRequestHandler {
private HandshakeHandler handshakeHandler;
@ -53,13 +51,13 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFact @@ -53,13 +51,13 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFact
public WebSocketHttpRequestHandler(WebSocketHandler webSocketHandler) {
Assert.notNull(webSocketHandler, "webSocketHandler is required");
this.handlerProvider = new HandlerProvider<WebSocketHandler>(webSocketHandler);
this.handlerProvider = new SimpleHandlerProvider<WebSocketHandler>(webSocketHandler);
this.handshakeHandler = new DefaultHandshakeHandler();
}
public WebSocketHttpRequestHandler( Class<? extends WebSocketHandler> webSocketHandlerClass) {
Assert.notNull(webSocketHandlerClass, "webSocketHandlerClass is required");
this.handlerProvider = new HandlerProvider<WebSocketHandler>(webSocketHandlerClass);
public WebSocketHttpRequestHandler( HandlerProvider<WebSocketHandler> handlerProvider) {
Assert.notNull(handlerProvider, "handlerProvider is required");
this.handlerProvider = handlerProvider;
}
public void setHandshakeHandler(HandshakeHandler handshakeHandler) {
@ -67,11 +65,6 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFact @@ -67,11 +65,6 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFact
this.handshakeHandler = handshakeHandler;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.handlerProvider.setBeanFactory(beanFactory);
}
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
@ -80,8 +73,7 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFact @@ -80,8 +73,7 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler, BeanFact
ServerHttpResponse httpResponse = new ServletServerHttpResponse(response);
try {
WebSocketHandler webSocketHandler = this.handlerProvider.getHandler();
this.handshakeHandler.doHandshake(httpRequest, httpResponse, webSocketHandler);
this.handshakeHandler.doHandshake(httpRequest, httpResponse, this.handlerProvider);
}
catch (Exception e) {
// TODO

94
spring-websocket/src/main/java/org/springframework/websocket/support/BeanCreatingHandlerProvider.java

@ -0,0 +1,94 @@ @@ -0,0 +1,94 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.util.Assert;
import org.springframework.websocket.HandlerProvider;
/**
* A {@link HandlerProvider} that uses {@link AutowireCapableBeanFactory#createBean(Class)
* creating a fresh instance every time #getHandler() is called.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class BeanCreatingHandlerProvider<T> implements HandlerProvider<T>, BeanFactoryAware {
private static final Log logger = LogFactory.getLog(BeanCreatingHandlerProvider.class);
private final Class<? extends T> handlerClass;
private AutowireCapableBeanFactory beanFactory;
public BeanCreatingHandlerProvider(Class<? extends T> handlerClass) {
Assert.notNull(handlerClass, "handlerClass is required");
this.handlerClass = handlerClass;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
if (beanFactory instanceof AutowireCapableBeanFactory) {
this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
}
}
public boolean isSingleton() {
return false;
}
public Class<? extends T> getHandlerType() {
return this.handlerClass;
}
public T getHandler() {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance for handler type " + this.handlerClass);
}
if (this.beanFactory == null) {
logger.warn("No BeanFactory available, attempting to use default constructor");
return BeanUtils.instantiate(this.handlerClass);
}
else {
return this.beanFactory.createBean(this.handlerClass);
}
}
@Override
public void destroy(T handler) {
if (this.beanFactory != null) {
if (logger.isTraceEnabled()) {
logger.trace("Destroying handler instance " + handler);
}
this.beanFactory.destroyBean(handler);
}
}
@Override
public String toString() {
return "BeanCreatingHandlerProvider [handlerClass=" + handlerClass + "]";
}
}

61
spring-websocket/src/main/java/org/springframework/websocket/support/SimpleHandlerProvider.java

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.websocket.support;
import org.springframework.util.ClassUtils;
import org.springframework.websocket.HandlerProvider;
/**
* A {@link HandlerProvider} that returns a singleton instance.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public class SimpleHandlerProvider<T> implements HandlerProvider<T> {
private final T handler;
public SimpleHandlerProvider(T handler) {
this.handler = handler;
}
@Override
public boolean isSingleton() {
return true;
}
@Override
public Class<?> getHandlerType() {
return ClassUtils.getUserClass(this.handler);
}
@Override
public T getHandler() {
return this.handler;
}
@Override
public void destroy(T handler) {
}
@Override
public String toString() {
return "SimpleHandlerProvider [handler=" + handler + "]";
}
}
Loading…
Cancel
Save